package dpss.commons;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
/**
 * 
 * @author Shewetaank Indora
 *
 */
public class Repo {
	
	// The repo path
	private String repoPath = null;

	/**
	 * Constructor, loading the repo path
	 */
	public Repo(String repoPath){
		this.repoPath = repoPath;
	}
	
	/**
	 * Gets the server information based on the IP address
	 * 
	 * @param IPport
	 * @return
	 * @throws IOException
	 * @throws ParserConfigurationException
	 * @throws SAXException
	 */
	public HashMap<String, String> getServerInfo(String ipAddress) throws IOException, ParserConfigurationException, SAXException{
		
		File xmlFile = new File(this.repoPath);
		DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
		Document doc = dBuilder.parse(xmlFile);
		
		NodeList nodeList = doc.getElementsByTagName("server");
		
		HashMap<String, String> hashMap = null;
		
		for(int temp = 0; temp<nodeList.getLength(); temp++){
			Node _node = nodeList.item(temp);
			Element element = (Element) _node;
				String[] _temp = ipAddress.split("\\.");
				String subnet = _temp[0];
				if(element.getAttribute("iprange").equalsIgnoreCase(subnet)){	
					hashMap = new HashMap<String, String>();
					hashMap.put("id", element.getAttribute("id"));
					hashMap.put("name", element.getAttribute("name"));
					hashMap.put("iprange", element.getAttribute("iprange"));
					hashMap.put("udpport", element.getAttribute("udpport"));
				}
			}
		
		return  hashMap;
	}
	
	/**
	 * Sets the server info on the repo
	 * 
	 * @param serverinfo
	 * @throws ParserConfigurationException
	 * @throws SAXException
	 * @throws IOException
	 * @throws TransformerException
	 */
	public void setServerInfo(Map<String, String> serverinfo) throws ParserConfigurationException, SAXException, IOException, TransformerException{
			
		File xmlFile = new File(this.repoPath);
		DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
		Document doc = dBuilder.parse(xmlFile);
		
		NodeList nodeList = doc.getElementsByTagName("server");
		
		for(int temp=0; temp<nodeList.getLength(); temp++){
			Node _node = nodeList.item(temp);
			Element element = (Element) _node;
			Iterator<Entry<String, String>> iter = serverinfo.entrySet().iterator();
			
			
			while(iter.hasNext()){
				Map.Entry<String, String> mEntry = (Map.Entry<String, String>) iter.next();
				if(mEntry.getKey().equalsIgnoreCase("id") && mEntry.getValue().equalsIgnoreCase(element.getAttribute("id"))){
					NamedNodeMap attr = _node.getAttributes();
					Node port = attr.getNamedItem("udpport");
					port.setTextContent(serverinfo.get("udpport"));	
					
					Node name = attr.getNamedItem("name");
					name.setTextContent(serverinfo.get("name"));
					
					Node iprange = attr.getNamedItem("iprange");
					iprange.setTextContent(serverinfo.get("iprange"));
				}
			}
		}
		TransformerFactory transformerFactory = TransformerFactory.newInstance();
		Transformer transformer = transformerFactory.newTransformer();
		DOMSource source = new DOMSource(doc);
		StreamResult result = new StreamResult(new File(this.repoPath));
		transformer.transform(source, result);
	}

	/**
	 * Returns the set of all the servers 
	 * @return
	 * @throws ParserConfigurationException 
	 * @throws IOException 
	 * @throws SAXException 
	 */
	public HashSet<HashMap<String, String>> getAllServers() throws ParserConfigurationException, SAXException, IOException {
		
		HashSet<HashMap<String, String>> serverSet = new HashSet<HashMap<String, String>>();
		
		File xmlFile = new File(this.repoPath);
		DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
		Document doc = dBuilder.parse(xmlFile);
		
		NodeList nodeList = doc.getElementsByTagName("server");

		for(int temp = 0; temp<nodeList.getLength(); temp++){
			HashMap<String, String> serverItem = new HashMap<String, String>();
			Element element = (Element) nodeList.item(temp);
			serverItem.put("id", element.getAttribute("id"));
			serverItem.put("name", element.getAttribute("name"));
			serverItem.put("iprange", element.getAttribute("iprange"));
			serverItem.put("udpport", element.getAttribute("udpport"));
			serverSet.add(serverItem);
		}

		return serverSet;
	}
	
	
	/**
	 * Given an IP address, returns the IP Range
	 * @param IpAddress
	 * @return
	 */
	public static String getIpRange(String IpAddress){
		String[] _temp = IpAddress.split("\\.");
		return _temp[0];
	}
}
